﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace Agile.Engine.Data
{
    public class DataAccess
    {
        /// <summary>
        /// 数据访问上下文
        /// </summary>
        public DataContext Context { get; set; }

        /// <summary>
        /// 映射表
        /// </summary>
        public string TableName { get; set; }

        /// <summary>
        /// 消息
        /// </summary>
        public string Message { get; set; }

        /// <summary>
        /// 获取空表格式
        /// </summary>
        /// <returns></returns>
        public DataTable GetSchema()
        {
            return Context.DefaultModel.QueryTable(TableName, "1=2");
        }

        /// <summary>
        /// 获取包含一个空行的数据表格式
        /// </summary>
        /// <returns></returns>
        public DataTable GetNewData(int count = 1)
        {
            var schema = GetSchema();
            for (var i = 0; i < count; i++)
                schema.Rows.Add(schema.NewRow());
            return schema;
        }

        /// <summary>
        /// 获取包含一个空行的数据表格式,用args初始化，必须格式相同
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public DataTable GetNewData(object[] args)
        {
            var schema = GetSchema();
            schema.Rows.Add(args);
            return schema;
        }

        /// <summary>
        /// 获取包含一个空行的数据表格式,用d初始化，只初始化字段系统的数据
        /// </summary>
        /// <param name="d"></param>
        /// <returns></returns>
        public DataTable GetNewData(System.Collections.IDictionary d)
        {
            var schema = GetNewData();
            var data = schema.Rows[0];
            foreach (DataColumn c in schema.Columns)
            {
                if (d.Contains(c.ColumnName))
                    data[c.ColumnName] = d[c.ColumnName];
            }
            return schema;
        }

        /// <summary>
        /// 获取全部数据
        /// </summary>
        /// <returns></returns>
        public DataTable GetData()
        {
            return Context.DefaultModel.QueryTable(TableName);
        }

        /// <summary>
        /// 获取指定ID的数据
        /// </summary>
        /// <returns></returns>
        public DataTable GetData(string sid)
        {
            var filter = "SID='{0}'";
            return Context.DefaultModel.QueryTable(TableName, string.Format(filter, sid));
        }

        /// <summary>
        /// 获取指定过滤的数据，空值不计入过滤条件
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public DataTable GetData(DataRow data)
        {
            var filter = Agile.Engine.Utils.DataUtils.ToFilter(data);
            return Context.DefaultModel.QueryTable(TableName, filter);
        }

        /// <summary>
        /// 获取指定过滤的数据，空值不计入过滤条件
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public DataTable GetData(System.Collections.IDictionary data)
        {
            var filter = Agile.Engine.Utils.DataUtils.ToFilter(data);
            return Context.DefaultModel.QueryTable(TableName, filter);
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public DataRow AddNew(DataRow data)
        {
            var schema = GetSchema();
            schema.Rows.Add(data.ItemArray);
            Context.DefaultModel.UpdateTable(schema);
            return data;
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public void AddNew(DataRow[] data)
        {
            var schema = GetSchema();
            foreach (var i in data)
                schema.Rows.Add(i.ItemArray);
            Context.DefaultModel.UpdateTable(schema);
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="data"></param>
        public void Update(params DataRow[] data)
        {
            var filter = Agile.Engine.Utils.DataUtils.ToFilter(data, "SID");

            var d = Context.DefaultModel.QueryTable(TableName, filter);

            foreach (var r in data)
            {
                var c = Agile.Engine.Utils.DataUtils.ScalarRow(d, "SID", r["SID"]);
                if (c != null && c.Length > 0)
                    c[0].ItemArray = r.ItemArray;
            }

            Context.DefaultModel.UpdateTable(d);
        }

        /// <summary>
        /// 按ID删除
        /// </summary>
        /// <param name="sid"></param>
        public void Delete(string sid)
        {
            var sql = "SID='{0}'";
            Context.DefaultModel.Delete(TableName, string.Format(sql, sid));
        }


        /// <summary>
        /// 按条件删除
        /// </summary>
        /// <param name="data"></param>
        public void Delete(DataRow data)
        {
            var filter = Agile.Engine.Utils.DataUtils.ToFilter(data);

            Context.DefaultModel.Delete(TableName, filter);
        }

        public DataTable Query(string filter)
        {
            return Context.DefaultModel.QueryTable(TableName, filter);
        }

        public T Scalar<T>(T value, string field, string filter)
            where T : struct
        {
            var sql = "SELECT {0} FROM {1} WHERE {2}";
            return Context.DefaultModel.ExecuteScalar(value, string.Format(sql, field, TableName, filter));
        }
        
        /// <summary>
        /// 是否存在
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public bool Exist(DataRow data)
        {
            return GetData(data).Rows.Count > 0;
        }
    }
}
